package com.kt.thread.demo;

import java.util.concurrent.CountDownLatch;

/**
 * Created by tangwy on 2016/9/13.
 */

/**
 * CountDownLatch典型用法是，将一个问题分成 N 个部分，用执行每个部分并让锁存器倒计数的 Runnable
 * 来描述每个部分，然后将所有 Runnable 加入到 Executor 队列。当所有的子部分完成后，协调线程就能够通过 await。
 */
public class CountDownLatchTest {
    private static final int SIZE=5;
    private static final CountDownLatch startSignal=new CountDownLatch(1);
    private static final CountDownLatch doneSignal=new CountDownLatch(SIZE);
    public static void test(){
        for (int i=0;i<SIZE;i++){
            new Thread(new Worker(startSignal,doneSignal,i+1)).start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        doOtherWork();
        try {
            doneSignal.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("所有工作线程准备完毕,开始正式工作............");
    }

    private static void doOtherWork(){
        System.out.println("其他线程做些其他的工作，完成后startSignal减1");
        startSignal.countDown();
    }

   static class Worker implements Runnable{
        private volatile int number;
        final CountDownLatch startSignal;
        final CountDownLatch doneSignal;
        public Worker(CountDownLatch startSignal,CountDownLatch doneSignal,int number){
            this.startSignal=startSignal;
            this.doneSignal=doneSignal;
            this.number=number;
        }
        @Override
        public void run() {
            try {
                //这里阻塞，只有startSignal这个计数到0时，下面的代码才开始执行

                startSignal.await();
                System.out.println("startSignal阻塞 ");
                //Thread.sleep(1000*number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(number+"号准备完毕");
            //doneSignal的计数减1
            doneSignal.countDown();
        }
    }
}

